package com.example.test20log.config;

import com.alibaba.nacos.api.config.listener.Listener;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.nologging.NoLoggingImpl;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.yaml.snakeyaml.Yaml;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.Executor;

/**
 * @Author: fxy
 * @Date: 2022/09/15/13:07
 * @Description:
 */

@Component
public class LogConfigListener implements Listener {
    @Autowired
    private ApplicationContext applicationContext;

    private static String currentLogConfig;

    @Override
    public Executor getExecutor() {
        return null;
    }

    @Override
    public void receiveConfigInfo(String s) {
        Yaml yaml = new Yaml();
        Map<String,Object> map = yaml.load(s);
        System.out.println(s);
        System.out.println(map);
        String logImplConfig;
        try {
            Map l1 = (Map)map.get("mybatis-plus");
            Map l2 = (Map) l1.get("configuration");
            logImplConfig = (String) l2.get("log-impl");
        }catch (Exception e){
            return;
        }
        if(StringUtils.isEmpty(logImplConfig)){
            return;
        }
        if(logImplConfig.equals(currentLogConfig)){
            return;
        }
        currentLogConfig = logImplConfig;
        try {
            transPrintLog();
        }catch (Exception e){

        }

    }

    private void transPrintLog() throws NoSuchFieldException, IllegalAccessException {
        Log log;
        if(currentLogConfig.equals("com.wpg.tools.mybatis.log.SelfStdOutImpl")){
            log = new StdOutImpl("");
        }else {
            log = new NoLoggingImpl("");
        }
        SqlSessionFactory sqlSessionFactory = applicationContext.getBean(SqlSessionFactory.class);
        Configuration configuration = sqlSessionFactory.getConfiguration();
        configuration.setLogImpl(NoLoggingImpl.class);
        Collection<MappedStatement> mappedStatements = configuration.getMappedStatements();
        for (Object mappedStatement : mappedStatements) {
            if(mappedStatement instanceof MappedStatement){
                Field field = mappedStatement.getClass().getDeclaredField("statementLog");
                field.setAccessible(true);
                field.set(mappedStatement, log);
            }else {
                System.out.println(mappedStatement);
                System.out.println(mappedStatement.getClass().getName());
            }
        }
    }
}
